#include "deerrxhandle.h"
#include "calibration.h"

extern QSerialPort     *serialPort;
DeerLink deer;
extern Widget *w;

QString FocDrive[] = {
    "通用设备",
    "一千四百瓦",
    "鹿人甲第二帅",
};
QString FocError[] = {
    "低电压",
    "高电压",
    "高温",
};

float DeerLink::getFloat(void)
{
    union {
        float fl;
        uint8_t data[4];
    }rx;
    rx.data[0] =this->buff[4];
    rx.data[1] =this->buff[5];
    rx.data[2] =this->buff[6];
    rx.data[3] =this->buff[7];

    return rx.fl;
}

uint8_t DeerLink::getUint8(void)
{
    return this->buff[4];
}

uint16_t DeerLink::getUint16(void)
{
    union {
        uint16_t u16;
        uint8_t data[2];
    }rx;
    rx.data[1] =this->buff[4];
    rx.data[0] =this->buff[5];

    return rx.u16;
}

int16_t DeerLink::getint16(void)
{
    union {
        int16_t u16;
        uint8_t data[2];
    }rx;
    rx.data[1] =this->buff[4];
    rx.data[0] =this->buff[5];

    return rx.u16;
}

/**
 * @brief  根据上位机命令做出对应响应
 * @param  void
 * @retval void
 */
void DeerSwitch(void)
{
    switch(deer.buff[3])
    {
    case M_Nume:
    {
        uint8_t drive = deer.getUint8();
        if (drive <= sizeof (FocDrive) / sizeof (QString)) {
            w->foc_name->setText(FocDrive[deer.getUint8()]);
            qDebug()<<"设备:"<<FocDrive[deer.getUint8()];
        } else {
            qDebug()<<"设备:"<<deer.getUint8();
        }
        break;
    }
    case M_Error:
    {
        QPalette qp;
        qp.setColor(QPalette::WindowText,Qt::red);
        w->foc_error->setPalette(qp);
        w->foc_error->setText(FocError[deer.buff[4]]);
        break;
    }
    case M_BatAdc:
    {
        float adc = (deer.buff[4]<<8 | deer.buff[5])/100.f;
        w->SetBatAdc(adc);
        break;
    }
    case M_Temp:
    {
        float adc = (deer.buff[4]<<8 | deer.buff[5])/100.f;
        w->SetTemp(adc);
        break;
    }
    case M_Angle:
    {
        float angle = deer.getFloat();

        c->showAngleAdd((double)(angle * 360));

        w->SetImageAngle(angle);
        break;
    }
    case M_Speed:
    {
        float speed = deer.getFloat();

        c->showSpeedAdd(speed);
        break;
    }
    case M_Iq:
    {
        float iq = deer.getFloat();

        c->showIqdAdd(iq);
        break;
    }
    case M_CalibPolarity:
    {
        short Polarity = deer.getint16();
        ca->CtrDebug("#388E3C", "编码器极性校准成功 Value:" + QString::number(Polarity));
        break;
    }
    case M_CalibPPnum:
    {
        uint16_t PPnum = deer.getUint16();
        ca->CtrDebug("#388E3C", "编码器磁极对数校准成功 Value:" + QString::number(PPnum));
        ca->SetIn_ppnum(PPnum);
        break;
    }
    case M_CalibR:
    {

        float r = deer.getFloat();
        ca->CtrDebug("#388E3C", "电机电阻校准成功 Value:" + QString::number(r));
        ca->SetIn_R(r);
        break;
    }
    case M_CalibL:
    {
        float l = deer.getFloat();

        ca->CtrDebug("#388E3C", "电机电感校准成功 Value:" + QString::number(l));
        ca->SetIn_L(l);
        break;
    }
    case M_EncError:
    {
        uint16_t error = deer.getUint16();
        ca->CtrDebug("#388E3C", "编码器误差校准成功 Value:" + QString::number(error));
        ca->SetIn_Angle0Value(error);
        break;
    }
    case M_CalibSucceed:
    {
        ca->CtrDebug("#00BCD4", "电机校准成功!!!");
    }
    }
}

/**
* @brief  上位机指令解析
 * @param  void
 * @retval void
 */
void DeerParsing(void)
{
    uint8_t ack;

    ack = 0;
    for (int i=0; i < deer.rxlen; i++) {
        ack += deer.buff[i];
    }

    if (ack == deer.buff[deer.rxlen]) {
        DeerSwitch();
    }
}

/**
* @brief  上位机指令接收
 * @param  void
 * @retval void
 */
void DeerRx(uint8_t data)
{
    switch(deer.step) {
        case 0:
            deer.cnt = 0;
            deer.buff[deer.cnt++] = data;
            if (data == 0xFD) {
                deer.step = 1;
            }
            break;
        case 1:
            deer.buff[deer.cnt++] = data;
            if (data == 0xDF) {
                deer.step = 2;
            } else {
                deer.step = 0;
            }
            break;
        case 2:
            deer.buff[deer.cnt++] = data;

            if (deer.cnt - 1 == 2) {
                deer.rxlen = data;
            }

            if (deer.cnt > deer.rxlen) {
                deer.step = 3;
                deer.cnt = 0;
            }

            break;

        default :
        {};
    }

    if (deer.step == 3) {
        DeerParsing();
        deer.step = 0;
    }
}

//实现run函数
void DeerRxHandle::run()
{
    //读取一个数据
    QByteArray temp = serialPort->readAll();
    int uartMaxLen = temp.length();

    if ( uartMaxLen != 0 ) {
        temp.resize(uartMaxLen);
        for (int i=0; i < uartMaxLen; i++) {
            uint8_t data = temp.at(i) & 0xff;
            DeerRx(data);
        }
    }
}
